﻿using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using ESRI.ArcGIS.Geodatabase;
using ESRI.ArcGIS.DataSourcesRaster;
using ESRI.ArcGIS.DataSourcesGDB;
using ESRI.ArcGIS.esriSystem;
using ESRI.ArcGIS.SpatialAnalyst;
using ESRI.ArcGIS.GeoAnalyst;
using ESRI.ArcGIS.Geometry;
using System.Xml;
using System.Text;

/// <summary>
/// DroughtIndexCalculator 的摘要说明
/// </summary>
public class DroughtIndexCalculator
{
	public DroughtIndexCalculator()
	{
	
	}  

    public string CalculateDroughtIndexToXmlDoc(string gpsSampleShapeFileName, string rasterName,
                                                string outFilepath, int blocksize, string rootid, DateTime imageDate, string imageType)
    {
        string time = imageDate.ToShortDateString();
        DroughtIndexCalculator dlc = new DroughtIndexCalculator();
        dlc.CheckDataExist(rootid,time,imageType);
        
        //IAoInitialize iAo = new AoInitializeClass();
        //iAo.Initialize(esriLicenseProductCode.esriLicenseProductCodeArcView);
        AoLicenseManager pAoLicenseManager = new AoLicenseManager();
        pAoLicenseManager.Initialize();
        
        string strFileLocation = outFilepath; //获取程序启动路径
        
        //if (iAo.IsProductCodeAvailable(esriLicenseProductCode.esriLicenseProductCodeArcView) == esriLicenseStatus.esriLicenseAvailable)
        //{

            try
            {
                //设置连接的服务器属性
                IPropertySet pInPropertySet = new PropertySetClass();
                pInPropertySet.SetProperty("SERVER", "192.168.2.51");
                pInPropertySet.SetProperty("INSTANCE", "5151");
                pInPropertySet.SetProperty("DATABASE", "");
                pInPropertySet.SetProperty("USER", "ct");
                pInPropertySet.SetProperty("PASSWORD", "xjct");
                pInPropertySet.SetProperty("VERSION", "sde.DEFAULT");

                IWorkspaceFactory pWorkFact = new SdeWorkspaceFactoryClass();
                //加载样点矢量文件
                IFeatureWorkspace featureWorkspace = (IFeatureWorkspace)pWorkFact.Open(pInPropertySet, 0);
                IFeatureClass pFClass = featureWorkspace.OpenFeatureClass(gpsSampleShapeFileName);
                
                int pointCount = pFClass.FeatureCount(null);
                IPointCollection pPointCol = dlc.LoadSamplePoint(pFClass,pointCount);

                int col, row;

                //定义一个存储结果的二维数组
                double[,] pIndex = new double[pointCount, 18];
                for (int i = 0; i < pointCount; i++)
                {
                    for (int j = 0; j < 18; j++)
                    {
                        pIndex[i, j] = 0;
                    }
                }


                string[] indexs = new string[18];
                if (imageType == "hyper")
                {
                    indexs = new string[18] { "XREDEDGE", "XVALDEPTH", "XWAVELEN", "XWAVEWID", "NDWI", "TVI", "NDVI",  "NSI", "WI", "NDGI", "GEMI", "EVI", "RVI", "ARVI", "SAVI", "MSAVI", "DVI", "RDVI" };
                }
                else
                {
                    indexs = new string[18] { "NDWI", "SPSI", "TVDI", "VSWI", "", "", "", "", "", "", "", "", "", "", "", "", "", ""};
                }
                

                IRasterWorkspaceEx rWorkSpace = (IRasterWorkspaceEx)pWorkFact.Open(pInPropertySet, 0);
                for (int j = 0; j < indexs.Length; j++)
                {
                    string indexRaster = indexs[j] + "_" + rasterName;

                    //判断提取旱情指数的影像文件是否存在
                    string sqlstr = "select table_name from all_tables where tablespace_name='XINJIANG'and table_name='" + indexRaster + "'";
                    System.Data.OleDb.OleDbDataReader dataReader = AccessDatabase.ExecuteReader(sqlstr);
                    bool exist = dataReader.HasRows;
                    if (exist)
                    {
                        IRasterDataset2 rDataSet = (IRasterDataset2)rWorkSpace.OpenRasterDataset(indexRaster);
                        IRaster2 pRaster = (IRaster2)rDataSet.CreateFullRaster();

                        //逐采样点求对应的blocksize*blocksize块的遥感指数
                        for (int i = 0; i < pointCount; i++)
                        {
                            //由平面坐标求像素的行列值
                            col = pRaster.ToPixelColumn(pPointCol.get_Point(i).X);
                            row = pRaster.ToPixelRow(pPointCol.get_Point(i).Y);
                            for (int k = col - (blocksize - 1) / 2; k <= col + (blocksize - 1) / 2; k++)
                            {
                                for (int l = row - (blocksize - 1) / 2; l <= row + (blocksize - 1) / 2; l++)
                                {
                                    pIndex[i, j] += Convert.ToDouble(pRaster.GetPixelValue(0, k, l));
                                }
                            }
                            pIndex[i, j] = pIndex[i, j] / (blocksize * blocksize);
                        }
                    }
                    else
                    {
                        for (int i = 0; i < pointCount; i++)
                        {
                            pIndex[i, j] = 0.0;
                        }
                    }
                }

                if (imageType == "hyper")
                {
                    strFileLocation = dlc.SaveRSIndexResult(pFClass, pointCount, pIndex, imageDate, outFilepath, strFileLocation,gpsSampleShapeFileName);
                }
                else
                {
                    strFileLocation = dlc.SaveIndexResult(pFClass, pointCount, pIndex, imageDate, outFilepath, strFileLocation);
                }
            }
          
            catch (Exception ex)
            {
                Log.WriteException(ex.Message);
                return "ERROR";
            }        

        //}
        //iAo.Shutdown();
        return strFileLocation;
    }


    //判断旱情指数表中是否存在指定日期和地区id的数据行，若存在，删除
    public void CheckDataExist(string rootid, string time,string imageType)
    {
        string commString = "";
        string deleteString = "";

        if (imageType == "hyper")
        {
            commString = "select * from sp_hyperindex where distid='" + rootid + "' and SAMPDATE=to_date('" + time + "','yyyy-mm-dd')";
        }
        else
        {
            commString = "select * from sp_droughtindex where distid='" + rootid + "' and SAMPDATE=to_date('" + time + "','yyyy-mm-dd')";
        }
        int resultRows = AccessDatabase.ExecuteSql(commString);
        if (resultRows == -1)
        {
            if (imageType == "hyper")
            {
                deleteString = "delete from sp_hyperindex where distid='" + rootid + "' and SAMPDATE=to_date('" + time + "','yyyy-mm-dd')";
            }
            else
            {
                deleteString = "delete from sp_droughtindex where distid='" + rootid + "' and SAMPDATE=to_date('" + time + "','yyyy-mm-dd')";
            }
            int deleteRows = AccessDatabase.ExecuteSql(deleteString);
        }
    }


    //加载样点特征文件，返回样点信息
    public IPointCollection LoadSamplePoint(IFeatureClass pFClass, int pointCount)
    {
        IPointCollection pPointCol = new MultipointClass();

        //样点经纬度定义         
        double x;
        double y;

        IPoint pPoint = new PointClass();
        IFeatureCursor featureCur = pFClass.Search(null, true);
        IFeature feature = featureCur.NextFeature();
        for (int k = 0; k < pointCount; k++)
        {
            IPoint pPoint1 = new PointClass();
            pPoint = (IPoint)feature.Shape;
            x = pPoint.X;
            y = pPoint.Y;
            pPoint1.PutCoords(x, y);
            object missing = Type.Missing;
            pPointCol.AddPoint(pPoint1, ref missing, ref missing);
            feature = featureCur.NextFeature();
        }

        return pPointCol;
    }


    //保存干旱指数计算结果到数据库表中，同时保存为本机的xml文件
    public string SaveIndexResult(IFeatureClass pFClass, int pointCount, double[,] pIndex, DateTime imageDate,string outFilepath, string strFileLocation)
    {
        string time = imageDate.ToShortDateString();

        //输出一个XML文件
        XmlDocument xmldoc = new XmlDocument();
        XmlElement reSamples;
        XmlElement[] point = new XmlElement[pointCount];

        IFeatureCursor featureCusor = pFClass.Search(null, false);
        IPoint xypoint = new PointClass();

        XmlElement pointid, lon, lat, xx, yy;
        XmlElement xmlSPSI, xmlNDWI, xmlTVDI, xmlVSWI;
      //  XmlElement DiseaseIndex;  // CHL_AB, LAI, MCL, LEAFGDW;
        string[] idList = new string[pointCount];


        reSamples = xmldoc.CreateElement("reSample");
        //保存到XML文档
        for (int h = 0; h < pointCount; h++)
        {
            IFeature feature1 = featureCusor.NextFeature();

            double ndwi = Convert.ToDouble(pIndex[h, 0].ToString("0.00"));
            double spsi = Convert.ToDouble(pIndex[h, 1].ToString("0.00"));
            double tvdi = Convert.ToDouble(pIndex[h, 2].ToString("0.00"));
            double vswi = Convert.ToDouble(pIndex[h, 3].ToString("0.00"));
            //       string time = imageDate.ToShortDateString();

            //插入数据行到数据库
            //string insertCommand = "insert into sp_droughtindex values('"
            //                            + feature1.get_Value(feature1.Fields.FindField("pointid")).ToString() + "',"
            //                            + "''" + ","
            //                            + "to_date('" + time + "','yyyy-mm-dd')" + ",'"
            //                            + feature1.get_Value(feature1.Fields.FindField("distid")).ToString() + "',"
            //                            + "''" + ","
            //                            + ndwi + ","
            //                            + spsi + ",'"
            //                            + feature1.get_Value(feature1.Fields.FindField("rootid")).ToString() + "')";

            string insertCommand = "insert into sp_droughtindex values('"
                                        + feature1.get_Value(feature1.Fields.FindField("pointid")).ToString() + "',"
                                        + "''" + ","
                                        + "to_date('" + time + "','yyyy-mm-dd')" + ",'"
                                        + feature1.get_Value(feature1.Fields.FindField("distid")).ToString() + "',"
                                        + "''" + ",'"
                                        + feature1.get_Value(feature1.Fields.FindField("rootid")).ToString() + "',"
                                        + ndwi + ","
                                        + spsi + ","
                                        + tvdi + ","
                                        + vswi + ")";

            int insertRow = AccessDatabase.ExecuteSql(insertCommand);

            point[h] = xmldoc.CreateElement("Parcel");

            pointid = xmldoc.CreateElement("pointid");
            pointid.InnerText = (string)feature1.get_Value(feature1.Fields.FindField("POINTID"));
            point[h].AppendChild(pointid);
            idList[h] = (string)feature1.get_Value(feature1.Fields.FindField("POINTID"));

            lon = xmldoc.CreateElement("Lon");
            lon.InnerText = Convert.ToString(feature1.get_Value(feature1.Fields.FindField("JIN")));
            point[h].AppendChild(lon);

            lat = xmldoc.CreateElement("Lat");
            lat.InnerText = Convert.ToString(feature1.get_Value(feature1.Fields.FindField("WEI")));
            point[h].AppendChild(lat);

            xx = xmldoc.CreateElement("X");
            xypoint = (IPoint)feature1.Shape;
            xx.InnerText = Convert.ToString(xypoint.X);
            point[h].AppendChild(xx);

            yy = xmldoc.CreateElement("Y");
            xypoint = (IPoint)feature1.Shape;
            yy.InnerText = Convert.ToString(xypoint.Y);
            point[h].AppendChild(yy);

            xmlNDWI = xmldoc.CreateElement("NDWI");
            xmlNDWI.InnerText = ndwi.ToString();
            point[h].AppendChild(xmlNDWI);

            xmlSPSI = xmldoc.CreateElement("SPSI");
            xmlSPSI.InnerText = spsi.ToString();
            point[h].AppendChild(xmlSPSI);

            xmlTVDI = xmldoc.CreateElement("TVDI");
            xmlTVDI.InnerText = tvdi.ToString();
            point[h].AppendChild(xmlTVDI);

            xmlVSWI = xmldoc.CreateElement("VSWI");
            xmlVSWI.InnerText = vswi.ToString();
            point[h].AppendChild(xmlVSWI);

            reSamples.AppendChild(point[h]);
        }

        xmldoc.AppendChild(reSamples);


        //保存样点指数xml文件
        strFileLocation = outFilepath; //获取程序启动路径  
        DateTime timeNow = imageDate;
        string timeString = timeNow.Year.ToString() + timeNow.Month.ToString() + timeNow.Day.ToString() + timeNow.Hour.ToString() + timeNow.Minute.ToString() + timeNow.Second.ToString();

        strFileLocation += timeString;
        strFileLocation += ".xml";

        xmldoc.Save(strFileLocation);

        return strFileLocation;

    }

    //保存高光谱指数计算结果到数据库表中，同时保存为本机的xml文件
    public string SaveRSIndexResult(IFeatureClass pFClass, int pointCount, double[,] pIndex, DateTime imageDate, string outFilepath, string strFileLocation, string gpsSampleShapeFileName)
    {
        string time = imageDate.ToShortDateString();

        //输出一个XML文件
        XmlDocument xmldoc = new XmlDocument();
        XmlElement reSamples;
        XmlElement[] point = new XmlElement[pointCount];

        IFeatureCursor featureCusor = pFClass.Search(null, false);
        IPoint xypoint = new PointClass();

        XmlElement pointid, lon, lat, xx, yy;
        XmlElement xmlXVALDEPTH, xmlXREDEDGE, xmlXWAVELEN, xmlXWAVEWID;
        XmlElement xmlNDWI, xmlTVI, xmlNDVI, xmlNSI, xmlWI, xmlNDGI, xmlGEMI, xmlEVI, xmlRVI, xmlARVI, xmlSAVI, xmlMSAVI, xmlDVI, xmlRDVI;
        //  XmlElement DiseaseIndex;  // CHL_AB, LAI, MCL, LEAFGDW;
        string[] idList = new string[pointCount];


        reSamples = xmldoc.CreateElement("reSample");
        //保存到XML文档
        for (int h = 0; h < pointCount; h++)
        {
            IFeature feature1 = featureCusor.NextFeature();

            double XREDEDGE = Convert.ToDouble(pIndex[h, 0].ToString("0.00"));
            double XVALDEPTH = Convert.ToDouble(pIndex[h, 1].ToString("0.00"));
            double XWAVELEN = Convert.ToDouble(pIndex[h, 2].ToString("0.00"));
            double XWAVEWID = Convert.ToDouble(pIndex[h, 3].ToString("0.00"));
            double NDWI  = Convert.ToDouble(pIndex[h, 4].ToString("0.00"));
            double TVI  = Convert.ToDouble(pIndex[h, 5].ToString("0.00"));
            double NDVI  = Convert.ToDouble(pIndex[h, 6].ToString("0.00"));
            double NSI  = Convert.ToDouble(pIndex[h, 7].ToString("0.00"));
            double WI  = Convert.ToDouble(pIndex[h, 8].ToString("0.00"));
            double NDGI  = Convert.ToDouble(pIndex[h, 9].ToString("0.00"));
            double GEMI  = Convert.ToDouble(pIndex[h, 10].ToString("0.00"));
            double EVI  = Convert.ToDouble(pIndex[h, 11].ToString("0.00"));
            double RVI  = Convert.ToDouble(pIndex[h, 12].ToString("0.00"));
            double ARVI  = Convert.ToDouble(pIndex[h, 13].ToString("0.00"));
            double SAVI  = Convert.ToDouble(pIndex[h, 14].ToString("0.00"));
            double MSAVI  = Convert.ToDouble(pIndex[h, 15].ToString("0.00"));
            double DVI  = Convert.ToDouble(pIndex[h, 16].ToString("0.00"));
            double RDVI = Convert.ToDouble(pIndex[h, 17].ToString("0.00"));
            //       string time = imageDate.ToShortDateString();

            //插入数据行到数据库
            //string insertCommand = "insert into sp_droughtindex values('"
            //                            + feature1.get_Value(feature1.Fields.FindField("pointid")).ToString() + "',"
            //                            + "''" + ","
            //                            + "to_date('" + time + "','yyyy-mm-dd')" + ",'"
            //                            + feature1.get_Value(feature1.Fields.FindField("distid")).ToString() + "',"
            //                            + "''" + ","
            //                            + ndwi + ","
            //                            + spsi + ",'"
            //                            + feature1.get_Value(feature1.Fields.FindField("rootid")).ToString() + "')";

            string insertCommand = "insert into sp_hyperindex values('"
                                        + feature1.get_Value(feature1.Fields.FindField("pointid")).ToString() + "',"
                                        + "''" + ","
                                        + "to_date('" + time + "','yyyy-mm-dd')" + ",'"
                                        + feature1.get_Value(feature1.Fields.FindField("distid")).ToString() + "',"
                                        + "''" + ",'"
                                        + feature1.get_Value(feature1.Fields.FindField("rootid")).ToString() + "',"
                                        + XREDEDGE + ","
                                        + XVALDEPTH + ","
                                        + XWAVELEN + ","
                                        + XWAVEWID + ","
                                        + NDWI + ","
                                        + TVI +","
                                        + NDVI +","
                                        + NSI +","
                                        + WI +","
                                        + NDGI +","
                                        + GEMI +","
                                        + EVI +","
                                        + RVI +","
                                        + ARVI +","
                                        + SAVI +","
                                        + MSAVI +","
                                        + DVI +","
                                        + RDVI +",'"
                                        + gpsSampleShapeFileName + "')";

            int insertRow = AccessDatabase.ExecuteSql(insertCommand);

            point[h] = xmldoc.CreateElement("Parcel");

            pointid = xmldoc.CreateElement("pointid");
            pointid.InnerText = (string)feature1.get_Value(feature1.Fields.FindField("POINTID"));
            point[h].AppendChild(pointid);
            idList[h] = (string)feature1.get_Value(feature1.Fields.FindField("POINTID"));

            lon = xmldoc.CreateElement("Lon");
            lon.InnerText = Convert.ToString(feature1.get_Value(feature1.Fields.FindField("JIN")));
            point[h].AppendChild(lon);

            lat = xmldoc.CreateElement("Lat");
            lat.InnerText = Convert.ToString(feature1.get_Value(feature1.Fields.FindField("WEI")));
            point[h].AppendChild(lat);

            xx = xmldoc.CreateElement("X");
            xypoint = (IPoint)feature1.Shape;
            xx.InnerText = Convert.ToString(xypoint.X);
            point[h].AppendChild(xx);

            yy = xmldoc.CreateElement("Y");
            xypoint = (IPoint)feature1.Shape;
            yy.InnerText = Convert.ToString(xypoint.Y);
            point[h].AppendChild(yy);

            xmlXREDEDGE = xmldoc.CreateElement("XREDEDGE");
            xmlXREDEDGE.InnerText = XREDEDGE.ToString();
            point[h].AppendChild(xmlXREDEDGE);

            xmlXVALDEPTH = xmldoc.CreateElement("XVALDEPTH");
            xmlXVALDEPTH.InnerText = XVALDEPTH.ToString();
            point[h].AppendChild(xmlXVALDEPTH);

            xmlXWAVELEN = xmldoc.CreateElement("XWAVELEN");
            xmlXWAVELEN.InnerText = XWAVELEN.ToString();
            point[h].AppendChild(xmlXWAVELEN);

            xmlXWAVEWID = xmldoc.CreateElement("XWAVEWID");
            xmlXWAVEWID.InnerText = XWAVEWID.ToString();
            point[h].AppendChild(xmlXWAVEWID);

            xmlNDWI = xmldoc.CreateElement("NDWI");
            xmlNDWI.InnerText = NDWI.ToString();
            point[h].AppendChild(xmlNDWI);

            xmlTVI = xmldoc.CreateElement("TVI");
            xmlTVI.InnerText = TVI.ToString();
            point[h].AppendChild(xmlTVI);

            xmlNDVI = xmldoc.CreateElement("NDVI");
            xmlNDVI.InnerText = NDVI.ToString();
            point[h].AppendChild(xmlNDVI);

            xmlNSI = xmldoc.CreateElement("NSI");
            xmlNSI.InnerText = NSI.ToString();
            point[h].AppendChild(xmlNSI);

            xmlWI = xmldoc.CreateElement("WI");
            xmlWI.InnerText = WI.ToString();
            point[h].AppendChild(xmlWI);

            xmlNDGI = xmldoc.CreateElement("NDGI");
            xmlNDGI.InnerText = NDGI.ToString();
            point[h].AppendChild(xmlNDGI);

            xmlGEMI = xmldoc.CreateElement("GEMI");
            xmlGEMI.InnerText = GEMI.ToString();
            point[h].AppendChild(xmlGEMI);

            xmlEVI = xmldoc.CreateElement("EVI");
            xmlEVI.InnerText = EVI.ToString();
            point[h].AppendChild(xmlEVI);

            xmlRVI = xmldoc.CreateElement("RVI");
            xmlRVI.InnerText = RVI.ToString();
            point[h].AppendChild(xmlRVI);

            xmlARVI = xmldoc.CreateElement("ARVI");
            xmlARVI.InnerText = ARVI.ToString();
            point[h].AppendChild(xmlARVI);

            xmlSAVI = xmldoc.CreateElement("SAVI");
            xmlSAVI.InnerText = SAVI.ToString();
            point[h].AppendChild(xmlSAVI);

            xmlMSAVI = xmldoc.CreateElement("MSAVI");
            xmlMSAVI.InnerText = MSAVI.ToString();
            point[h].AppendChild(xmlMSAVI);

            xmlDVI = xmldoc.CreateElement("DVI");
            xmlDVI.InnerText = DVI.ToString();
            point[h].AppendChild(xmlDVI);

            xmlRDVI = xmldoc.CreateElement("RDVI");
            xmlRDVI.InnerText = RDVI.ToString();
            point[h].AppendChild(xmlRDVI);

            reSamples.AppendChild(point[h]);
        }

        xmldoc.AppendChild(reSamples);


        //保存样点指数xml文件
        strFileLocation = outFilepath; //获取程序启动路径  
        DateTime timeNow = imageDate;
        string timeString = timeNow.Year.ToString() + timeNow.Month.ToString() + timeNow.Day.ToString() + timeNow.Hour.ToString() + timeNow.Minute.ToString() + timeNow.Second.ToString();

        strFileLocation += timeString;
        strFileLocation += ".xml";

        xmldoc.Save(strFileLocation);

        return strFileLocation;

    }
}
